#pragma once

#define DEBUG

#ifdef DEBUG

#include <iostream>

#endif

#include "defines.h"
#include "vector.h"
#include "plane.h"
#include "color.h"

struct BufferData {
 number depth;
 MultiColor colors;
};

struct Renderer {

 number distance;

 Vector<2> middle;

 Plane<BufferData> buffer;

 Plane<Color> screen;

 Vector<2> project(Vector<3> point) {
  if (point.z() > 0) {
   number z = point.z() + distance;
   return Vector<2>{{point.x() * distance / z,point.y() * distance / z}};
  } else {
   return Vector<2>{{point.x(),point.y()}};
  }
 }

 void drawPoint(Vector<3> point,Color color) {
  Vector<2> transformed = project(point);
  transformed += middle;
  if ((not transformed.x()) or (not transformed.y()) or (transformed.x() > screen.width) or (transformed.y() > screen.height)) return;
  if (buffer[transformed].depth < point.z()) return;
  bool transparent = color.transparent();
  if (not transparent) buffer[transformed].depth = point.z();
  else color.multiply();
  buffer[transformed].colors += color;
 }
 
 void drawToScreen(void) {
  for (int i = 0;i < screen.size;++i) {
   screen.points[i] = buffer.points[i].colors;
  }
 }

 Renderer(number x,number y,number z,number d) : distance(d),middle{{x / 2,y / 2}},buffer(x,y,{z}),screen(x,y,{0,0,0,0}) {

 }

};
